#ifndef INTERFGRAPH_HPP_
#define INTERFGRAPH_HPP_

#include<vector>
#include<map>
#include<set>
#include"common.hpp"
#include"RegMask.hpp"

class Instruction;
class SimdOperand;

enum RegClass{
	CALLER_SAVE = 0x001,
	CALLEE_SAVE = 0x002,
	MACRO_REGISTER= = 0x004
};

class InterfGraph{
	struct PseudoReg{
		int pseudo_reg;//id of pseudo register 
		unsigned int flags;
		TargetInfo::PhysicalRegister physical_register;

		std::vector<Instruction*> defs;
		std::vector<Instruction*> uses;

		std::set<int> interfs;

		bool assigned;
		bool add_interf(int id)
		{
			return (interfs.insert(id)).second;
		}
		void add_use(Instruction * instr)
		{
			uses.push_back(instr);
		}
		void add_def(Instruction * instr)
		{
			defs.push_back(instr);
		}
		void set_symbol_id(int id)
		{ 	
			pseudo_reg = id; 
		}
		bool is_assigned()
		{
			return assigned;	
		}
		bool is_macro_symbol();
		PseudoReg(): assigned(false)
		{
			physical_register = (enum TargetInfo::PhysicalRegister)0;
		}
	};
	std::map<int, PseudoReg> adjtable;
	//for vector data-register 
	std::map<int, int*> vector_associate_info;
	
	//add the edge between x and y;			
	void add_interference(int x, int y);
	void assign_physical_register(int id, enum TargetInfo::PhysicalRegister physical_register);
	void free_vector_associate_info();
	RegMask get_prevent_mask(int id);
public:
	void build_interference(int id, std::set<int> const & inferences); 
	void add_use(Instruction * instr, int pseudo_reg);
	void add_def(Instruction * instr, int pseudo_reg);
	void mark_callee_save(int id);
	void build_vector_associate_info(const SimdOperand * opd);
	void color_register();
};
#endif
